package gameStates;

import interfaces.superWidgets.ListenerKeeperElement;

import java.util.HashMap;

import main.InitGame;
import main.listeners.KeeperContainer;
import main.listeners.ListenerClearer;
import main.listeners.ListenerKeeper;
import main.listeners.StatusKeeperContainer;
import main.listeners.StatusListenerKeeper;

import com.jmex.game.state.GameState;

public abstract class SimpleGameState extends GameState implements ListenerKeeperElement {
	
	protected HashMap<Class<?>, ListenerClearer> listenerClearers;
	
	protected HashMap<ListenerKeeper, KeeperContainer> keeperContainers; 
	protected HashMap<StatusListenerKeeper, StatusKeeperContainer> statusKeeperContainers; 
	
	public SimpleGameState(String name) {
		super();
		
		setName(name);
		
		listenerClearers = new HashMap<Class<?>, ListenerClearer>();
		
		keeperContainers = new HashMap<ListenerKeeper, KeeperContainer>();
		statusKeeperContainers = new HashMap<StatusListenerKeeper, StatusKeeperContainer>();
	}
	
	/**
	 * Restores this {@link GameState}.
	 */
	public void restore() {
		cleanKeeperContainers();
	}
	
	protected void cleanKeeperContainers() {
		for(KeeperContainer c : keeperContainers.values()) {
			c.cleanUp();
		}
		keeperContainers.clear();
		
		for(StatusKeeperContainer c : statusKeeperContainers.values()) {
			c.cleanUp();
		}
		statusKeeperContainers.clear();
	}
	
	@Override
	public void cleanup() {
		for(ListenerClearer clearer : listenerClearers.values()) {
			clearer.clear();
		}
		listenerClearers.clear();
		
		cleanKeeperContainers();
	}
	
	public void addListenerToClearer(Object l) {
		Class<?> listenerClass = l.getClass().getInterfaces()[0];
		ListenerClearer clearer = listenerClearers.get(listenerClass);
		
		if(clearer == null) {
			clearer = InitGame.get().createNewListenerClearer(listenerClass);
			listenerClearers.put(listenerClass, clearer);
		}
		
		assert(clearer != null);
		clearer.addListener(l);
	}
	
	@Override
	public void addListener(ListenerKeeper keeper, Object listener) {
		KeeperContainer container = keeperContainers.get(keeper);
		if(container == null) {
			container = new KeeperContainer(keeper);
			keeperContainers.put(keeper, container);
		}
		assert(container != null);
		
		container.addListener(listener);
	}
	
	public void addStatusListener(StatusListenerKeeper keeper, Object listener, float diff) {
		StatusKeeperContainer container = statusKeeperContainers.get(keeper);
		if(container == null) {
			container = new StatusKeeperContainer(keeper);
			statusKeeperContainers.put(keeper, container);
		}
		assert(container != null);
		
		container.setDiff(diff);
		container.addListener(listener);
	}
}